package vip.xiaomoli.idempotent.component;

import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DBCleaner {

    private static final int DATA_RETENTION_HOURS = 24;

    public DBCleaner(DataSource dataSource) {
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(
                () -> {
                    while (deleteIdempotent(dataSource)) {}
                },
                3600, 3600, TimeUnit.SECONDS
        );
    }

    private boolean deleteIdempotent(DataSource dataSource) {
        boolean isContinue = true;
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DataSourceUtils.getConnection(dataSource);
            String sql = "DELETE FROM idempotent WHERE addTime < ? LIMIT 500";
            pstmt = conn.prepareStatement(sql);
            pstmt.setTimestamp(1, new Timestamp(getHoursAgo().getTime()));
            if (0 == pstmt.executeUpdate()) isContinue = false;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeStatement(pstmt);
            DataSourceUtils.releaseConnection(conn, dataSource);
        }
        return isContinue;
    }

    private Date getHoursAgo() {
        final Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.HOUR, -DATA_RETENTION_HOURS);
        return c.getTime();
    }

}
